// multiboot info

/*
   Copyright 2005 Corey Tabaka

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#ifndef __KERNEL_MULTIBOOT_H__
#define __KERNEL_MULTIBOOT_H__

#include "ktypes.h"

/* Macros. */
     
/* The magic number for the Multiboot header. */
#define MULTIBOOT_HEADER_MAGIC          0x1BADB002

/* The flags for the Multiboot header. */
#ifdef __ELF__
# define MULTIBOOT_HEADER_FLAGS         0x00000003
#else
# define MULTIBOOT_HEADER_FLAGS         0x00010003
#endif

/* The magic number passed by a Multiboot-compliant boot loader. */
#define MULTIBOOT_BOOTLOADER_MAGIC      0x2BADB002

/* C symbol format. HAVE_ASM_USCORE is defined by configure. */
#ifdef HAVE_ASM_USCORE
# define EXT_C(sym)                     _ ## sym
#else
# define EXT_C(sym)                     sym
#endif

#ifndef ASM
/* Do not include here in boot.S. */

/* Types. */

/* The Multiboot header. */
typedef struct multiboot_header
{
	uint32 magic;
	uint32 flags;
	uint32 checksum;
	uint32 header_addr;
	uint32 load_addr;
	uint32 load_end_addr;
	uint32 bss_end_addr;
	uint32 entry_addr;
} multiboot_header_t;

/* The symbol table for a.out. */
typedef struct aout_symbol_table
{
	uint32 tabsize;
	uint32 strsize;
	uint32 addr;
	uint32 reserved;
} aout_symbol_table_t;

/* The section header table for ELF. */
typedef struct elf_section_header_table
{
	uint32 num;
	uint32 size;
	uint32 addr;
	uint32 shndx;
} elf_section_header_table_t;

/* The Multiboot information. */
typedef struct multiboot_info
{
	uint32 flags;
	uint32 mem_lower;
	uint32 mem_upper;
	uint32 boot_device;
	uint32 cmdline;
	uint32 mods_count;
	uint32 mods_addr;
	union
	{
		aout_symbol_table_t aout_sym;
		elf_section_header_table_t elf_sec;
	} u;
	uint32 mmap_length;
	uint32 mmap_addr;
} multiboot_info_t;

enum {
	MB_INFO_MEM_SIZE	= 0x001,
	MB_INFO_BOOT_DEV	= 0x002,
	MB_INFO_CMD_LINE	= 0x004,
	MB_INFO_MODS		= 0x008,
	MB_INFO_SYMS		= 0x010,
	MB_INFO_MMAP		= 0x020,
	MB_INFO_DRIVES		= 0x040,
	MB_INFO_CONFIG		= 0x080,
	MB_INFO_BOOT_LOADER	= 0x100,
	MB_INFO_APM_TABLE	= 0x200,
	MB_INFO_VBE			= 0x400,
};

/* The module structure. */
typedef struct module
{
	uint32 mod_start;
	uint32 mod_end;
	uint32 string;
	uint32 reserved;
} module_t;

/* The memory map. Be careful that the offset 0 is base_addr_low but no size. */
typedef struct memory_map
{
	uint32 size;
	uint32 base_addr_low;
	uint32 base_addr_high;
	uint32 length_low;
	uint32 length_high;
	uint32 type;
} memory_map_t;

/* Memory map entry types */
enum {
	MB_MMAP_TYPE_AVAILABLE		= 0x01,
	MB_MMAP_TYPE_RESERVED		= 0x02,
	MB_MMAP_TYPE_ACPI_RECLAIM	= 0x03,
	MB_MMAP_TYPE_ACPI_NVS		= 0x04,
};

#endif

#endif
